﻿using JuCheap.Core.Data;
using JuCheap.Core.Infrastructure.Exceptions;
using JuCheap.Core.Infrastructure.Extentions;
using JuCheap.Core.IRepository;
using JuCheap.Core.Repository;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Data;
using System.Linq;
using static JuCheap.Core.Infrastructure.Utilities.Constants;

namespace JuCheap.Core.Service
{
    /// <summary>
    /// 依赖注入模块初始化
    /// </summary>
    public static class JuCheapServiceModuleInitialize
    {
        /// <summary>
        /// 添加数据库初始配置
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        public static void AddJuCheapDatabase(this IServiceCollection services, IConfiguration configuration)
        {
            var dbType = configuration.GetSection("ConnectionStrings:DbType").Value;
            if (dbType.IsEqual(DatabaseConstValue.MySqlDbType))
            {
                services.AddDbContext<JuCheapContext>(options => options.UseMySql(configuration.GetConnectionString("Connection_MySql"), null));
            }
            else if (dbType.IsEqual(DatabaseConstValue.SqlServerDbType))
            {
                services.AddDbContext<JuCheapContext>(options => options.UseSqlServer(configuration.GetConnectionString("Connection_SqlServer")));
            }
            else
            {
                throw new BusinessException($"没有找到对应类型的数据库配置{dbType}");
            }
        }

        /// <summary>
        /// 添加需要依赖注入的服务
        /// </summary>
        /// <param name="services"></param>
        public static void AddJuCheapService(this IServiceCollection services)
        {
            //2.1.工作单元
            services.AddScoped<IUnitWork, UnitWork>();

            //2.2.通过反射，批量取出需要注入的仓储接口和仓储实现类
            var repositoryRegistrations =
                from type in typeof(RepositoryBase<>).Assembly.GetTypes()
                where type.Namespace != null && (type.Namespace.IsNotBlank() &&
                                               type.Namespace.Contains("JuCheap.Core.Repository") &&
                                               type.GetInterfaces().Any(x => x.Name.EndsWith("Repository")) &&
                                               type.GetInterfaces().Any())
                select new { Service = type.GetInterfaces().First(), Implementation = type };

            foreach (var t in repositoryRegistrations)
            {
                services.AddScoped(t.Service, t.Implementation);
            }

            //3.通过反射，批量取出需要注入的服务接口和服务实现类
            var serviceRegistrations =
                from type in typeof(JuCheapServiceModuleInitialize).Assembly.GetTypes()
                where type.Namespace != null && (type.Namespace.IsNotBlank() &&
                                               type.Namespace.Contains("JuCheap.Core.Service") &&
                                               type.GetInterfaces().Any(x => x.Name.EndsWith("Service")) &&
                                               type.GetInterfaces().Any())
                select new { Service = type.GetInterfaces().First(), Implementation = type };

            foreach (var t in serviceRegistrations)
            {
                services.AddScoped(t.Service, t.Implementation);
            }

            //4.使用automapper
            services.UseAutoMapperExtention();
        }
    }
}
